home *** CD-ROM | disk | FTP | other *** search
/ System Booster / System Booster.iso / Archives / GNU / GNUPLOTsrc.lha / term / pslatex.trm < prev    next >
Encoding:
Text File  |  1996-01-22  |  13.8 KB  |  513 lines

  1. /*
  2.  * $Id: pslatex.trm,v 1.18 1995/12/20 21:48:08 drd Exp $
  3.  */
  4.  
  5. /* GNUPLOT - pslatex.trm */
  6. /*
  7.  * Copyright (C) 1990 - 1993   
  8.  *
  9.  * Permission to use, copy, and distribute this software and its
  10.  * documentation for any purpose with or without fee is hereby granted, 
  11.  * provided that the above copyright notice appear in all copies and 
  12.  * that both that copyright notice and this permission notice appear 
  13.  * in supporting documentation.
  14.  *
  15.  * Permission to modify the software is granted, but not the right to
  16.  * distribute the modified code.  Modifications are to be distributed 
  17.  * as patches to released version.
  18.  *  
  19.  * This software  is provided "as is" without express or implied warranty.
  20.  * 
  21.  * This file is included by ../term.c.
  22.  *
  23.  * This file supplies the terminal drivers:
  24.  *     pslatex --latex with embedded postscript
  25.  *     pstex   --plain TeX with embedded postscript
  26.  *
  27.  * AUTHORS
  28.  *  George Phillips
  29.  *  Russell Lang
  30.  *  David Kotz
  31.  * 
  32.  * send your comments or suggestions to (info-gnuplot@dartmouth.edu).
  33.  */
  34.  
  35. #ifndef GOT_DRIVER_H
  36. #include "driver.h"
  37. #endif
  38.  
  39. #ifdef TERM_REGISTER
  40. register_term(pslatex)
  41. register_term(pstex)
  42. #endif
  43.  
  44. #ifdef TERM_PROTO
  45. TERM_PUBLIC void PSLATEX_options __P((void));
  46. TERM_PUBLIC void PSLATEX_init __P((void));
  47. TERM_PUBLIC void PSLATEX_graphics __P((void));
  48. TERM_PUBLIC void PSLATEX_put_text __P((unsigned int x, unsigned int y, char str[]));
  49. TERM_PUBLIC int PSLATEX_justify_text __P((enum JUSTIFY mode));
  50. TERM_PUBLIC int PSLATEX_text_angle __P((int angle));
  51. TERM_PUBLIC void PSLATEX_reset __P((void));
  52. TERM_PUBLIC void PSLATEX_text __P((void));
  53. TERM_PUBLIC void PSLATEX_move __P((unsigned int x, unsigned int y));
  54. TERM_PUBLIC void PSLATEX_vector __P((unsigned int x, unsigned int y));
  55. TERM_PUBLIC void PSLATEX_linetype __P((int lt));
  56. TERM_PUBLIC void PSLATEX_point __P((unsigned int x,unsigned int y, int number));
  57.  
  58. #define PSLATEX_XMAX (5*720)
  59. #define PSLATEX_YMAX (3*720)
  60.  
  61. /* 10 pt char is about 10 pts high (say) */
  62. #define PSLATEX_VCHAR (100)
  63. /* 10 pt char is about 6 pts wide (say) */
  64. /* I find about 5 points (output from test) - div */
  65. #define PSLATEX_HCHAR (50)
  66. #define GOT_PSLATEX_PROTO
  67. #endif
  68.  
  69. #ifndef TERM_PROTO_ONLY
  70.  
  71. #ifdef TERM_BODY
  72. static int PSLATEX_angle;
  73. static int PSLATEX_justify;
  74. static int PSLATEX_rotate = TRUE;
  75. static char PSLATEX_psfile[MAX_ID_LEN+1] = "";
  76. static TBOOLEAN PSLATEX_useAuxFile = FALSE; /* do we write two files? */
  77. static FILE *PSLATEX_auxFile;
  78. static TBOOLEAN PSLATEX_output = TRUE; /* do we write LaTeX? */
  79.  
  80. struct text_command {
  81.     int x, y, angle, justify;
  82.     char* label;
  83.     struct text_command* next;
  84. };
  85.  
  86. static struct text_command* PSLATEX_labels;
  87.  
  88. TERM_PUBLIC void PSLATEX_options()
  89. {
  90.     if (!END_OF_COMMAND) {
  91.     if (almost_equals(c_token, "d$efault")) {
  92.         ps_color = FALSE;
  93.         PSLATEX_rotate = TRUE;
  94.         PSLATEX_useAuxFile = FALSE;
  95.         c_token++;
  96.     }
  97.     }
  98.  
  99.     if (!END_OF_COMMAND) {
  100.     if (almost_equals(c_token, "c$olor")) {
  101.         ps_color = TRUE;
  102.         c_token++;
  103.     }
  104.     }
  105.  
  106.     if (!END_OF_COMMAND) {
  107.     if (almost_equals(c_token, "m$onochrome")) {
  108.         ps_color = FALSE;
  109.         c_token++;
  110.     }
  111.     }
  112.  
  113.     if (!END_OF_COMMAND) {
  114.     if (almost_equals(c_token, "r$otate")) {
  115.         PSLATEX_rotate = TRUE;
  116.         c_token++;
  117.     }
  118.     }
  119.  
  120.     if (!END_OF_COMMAND) {
  121.     if (almost_equals(c_token, "n$orotate")) {
  122.         PSLATEX_rotate = FALSE;
  123.         c_token++;
  124.     }
  125.     }
  126.  
  127.     if (!END_OF_COMMAND) {
  128.     if (almost_equals(c_token, "a$uxfile")) {
  129.         PSLATEX_useAuxFile = TRUE;
  130.         c_token++;
  131.     }
  132.     }
  133.     /* div */
  134.  
  135.     if (!END_OF_COMMAND) {
  136.         /* We have font size specified */
  137.         struct value a;
  138.         int ps_fontsize = (int)real(const_express(&a));
  139.         term->v_char = (unsigned int)(ps_fontsize*PS_SC);
  140.         term->h_char = (unsigned int)(ps_fontsize*PS_SC/2);
  141.     }
  142.  
  143.     /* be sure to generate an options string that PSLATEX_init understands */
  144.  
  145.     sprintf(term_options, "%s %s%s",
  146.         ps_color ? "color" : "monochrome",
  147.         PSLATEX_rotate ? "rotate" : "norotate",
  148.         PSLATEX_useAuxFile ? " auxfile" : "");
  149. }
  150.  
  151. TERM_PUBLIC void PSLATEX_init()
  152. {
  153.     extern char outstr[];    /* name of output file in quotes */
  154.  
  155.     if (strcmp(term->name, "pstex") == 0)
  156.         PSLATEX_output = FALSE;
  157.  
  158.     /* try to open the auxiliary file for the postscript parts. */
  159.     if (PSLATEX_useAuxFile == TRUE) {
  160.     char *dotIndex;
  161.  
  162.     /* assume file name is ending in ".tex" */
  163.     strcpy(PSLATEX_psfile, outstr+1);
  164.     dotIndex = strrchr(PSLATEX_psfile,'.');
  165.     if (dotIndex) {
  166.         strcpy(dotIndex,".ps");
  167.         if ((PSLATEX_auxFile = fopen(PSLATEX_psfile,"w")) == (FILE *)NULL){
  168.         PSLATEX_useAuxFile = FALSE;
  169.         fprintf(stderr,"Cannot open aux file %s for output\n",
  170.             PSLATEX_psfile);
  171.         }
  172.     } else {
  173.         fprintf(stderr,"Cannot make PostScript file name from %s\n",
  174.             outstr);
  175.         fprintf(stderr,"Turning off auxfile option\n");
  176.         PSLATEX_useAuxFile = FALSE;
  177.     }
  178.     }
  179.  
  180.     if (PSLATEX_output) {
  181.         fprintf(outfile, "%% GNUPLOT: LaTeX picture with Postscript\n");
  182.     fprintf(outfile, "\\setlength{\\unitlength}{0.1bp}\n");
  183.     } else {
  184.  
  185.         /* write plain TeX header */
  186.  
  187.         fprintf(outfile, "%% GNUPLOT: plain TeX with Postscript\n");
  188.     fprintf(outfile, "\\expandafter\\ifx\\csname GNUPLOTpicture\\endcsname\\relax\n");
  189.     fprintf(outfile, "  \\newdimen\\GNUPLOTunit\n");
  190.     fprintf(outfile, "  \\GNUPLOTunit=0.1bp\n");
  191.     fprintf(outfile, "  \\def\\GNUPLOTpicture(#1,#2){\\vbox to#2\\GNUPLOTunit\\bgroup\n");
  192.     fprintf(outfile, "    \\def\\put(##1,##2)##3{\\unskip\\raise##2\\GNUPLOTunit\n");
  193.     fprintf(outfile, "      \\hbox to0pt{\\kern##1\\GNUPLOTunit ##3\\hss}\\ignorespaces}%%\n");
  194.     fprintf(outfile, "    \\def\\ljust##1{\\vbox to0pt{\\vss\\hbox to0pt{##1\\hss}\\vss}}%%\n");
  195.     fprintf(outfile, "    \\def\\cjust##1{\\vbox to0pt{\\vss\\hbox to0pt{\\hss ##1\\hss}\\vss}}%%\n");
  196.     fprintf(outfile, "    \\def\\rjust##1{\\vbox to0pt{\\vss\\hbox to0pt{\\hss ##1}\\vss}}%%\n");
  197.     fprintf(outfile, "    \\def\\stack##1{\\let\\\\=\\cr\\tabskip=0pt\\halign{\\hfil ####\\hfil\\cr ##1\\crcr}}%%\n");
  198.     fprintf(outfile, "    \\def\\lstack##1{\\hbox to0pt{\\vbox to0pt{\\vss\\stack{##1}}\\hss}}%%\n");
  199.     fprintf(outfile, "    \\def\\cstack##1{\\hbox to0pt{\\hss\\vbox to0pt{\\vss\\stack{##1}}\\hss}}%%\n");
  200.     fprintf(outfile, "    \\def\\rstack##1{\\hbox to0pt{\\vbox to0pt{\\stack{##1}\\vss}\\hss}}%%\n");
  201.     fprintf(outfile, "    \\vss\\hbox to#1\\GNUPLOTunit\\bgroup\\ignorespaces}%%\n");
  202.     fprintf(outfile, "  \\def\\endGNUPLOTpicture{\\hss\\egroup\\egroup}%%\n");
  203.     fprintf(outfile, "\\fi\n");
  204.     }
  205.  
  206.     {
  207.         unsigned int xmin = xoffset * PSLATEX_XMAX / PS_SC;
  208.         unsigned int xmax = (xoffset+xsize) * PSLATEX_XMAX / PS_SC;
  209.         unsigned int ymin = yoffset * PSLATEX_YMAX / PS_SC;
  210.         unsigned int ymax = (yoffset+ysize) * PSLATEX_YMAX / PS_SC;
  211.  
  212.         if (PSLATEX_useAuxFile) {
  213.             FILE *tmp = outfile;
  214.             outfile = PSLATEX_auxFile;
  215.             PS_common_init(1,1,0, 0,0, xmin, ymin, xmax, ymax, NULL);
  216.             outfile = tmp;
  217.         } else {
  218.             fprintf(outfile, "\\special{!\n");
  219.             PS_common_init(1,1,0, 0,0, xmin, ymin, xmax, ymax, NULL);
  220.             fprintf(outfile, "}\n");
  221.         }
  222.     }
  223.  
  224.     PSLATEX_angle = 0;
  225.     PSLATEX_justify = 0;
  226.     PSLATEX_labels = 0;
  227. }
  228.  
  229. TERM_PUBLIC void PSLATEX_graphics()
  230. {
  231.     struct termentry *t = term;
  232.  
  233.     /* bounding box = all if multiplot, or size if not */
  234.     double xscale = multiplot ? 1 : xsize;
  235.     double yscale = multiplot ? 1 : ysize;
  236.  
  237.     if (PSLATEX_output)
  238.         fprintf(outfile, "\\begin{picture}(%d,%d)(0,0)\n", (int)(xscale*t->xmax), (int)(yscale*t->ymax));
  239.     else
  240.         fprintf(outfile, "\\GNUPLOTpicture(%d,%d)\n", (int)(xscale*t->xmax), (int)(yscale*t->ymax));
  241.  
  242.     if (PSLATEX_useAuxFile) {
  243.     FILE *tmp;
  244.     /*
  245.      * these are taken from the post.trm file computation
  246.      * of the bounding box, but without the X_OFF and Y_OFF
  247.      */
  248.     int urx = (int)(xscale * (PS_XMAX) / PS_SC + 0.5),
  249.         ury = (int)(yscale * (PS_YMAX) / PS_SC + 0.5);
  250.  
  251.     /* generate special which xdvi and dvips can handle */
  252.     fprintf(outfile,
  253.         "\\special{psfile=%s llx=0 lly=0 urx=%d ury=%d rwi=%d}\n",
  254.         PSLATEX_psfile, urx, ury, 10*urx);
  255.     tmp = outfile;
  256.     outfile = PSLATEX_auxFile;
  257.     PS_graphics();
  258.     outfile = tmp;
  259.     } else {
  260.     fprintf(outfile, "\\special{\"\n");
  261.     PS_graphics();
  262.     }
  263.  
  264.     PSLATEX_labels = (struct text_command *)NULL;
  265. }
  266.  
  267. TERM_PUBLIC void PSLATEX_put_text(x, y, str)
  268. unsigned int x, y;
  269. char str[];
  270. {
  271.     struct text_command* tc;
  272.  
  273.     /* ignore empty strings */
  274.     if (str[0] == '\0')
  275.     return;
  276.     
  277.     tc = (struct text_command*)alloc(sizeof(struct text_command), term->name);
  278.     tc->x = x;
  279.     tc->y = y;
  280.     tc->label = (char *)alloc(strlen(str) + 1, term->name);
  281.     strcpy(tc->label, str);
  282.     tc->justify = PSLATEX_justify;
  283.     tc->angle = PSLATEX_angle;
  284.  
  285.     tc->next = PSLATEX_labels;
  286.     PSLATEX_labels = tc;
  287. }
  288.  
  289. TERM_PUBLIC int PSLATEX_justify_text(mode)
  290. enum JUSTIFY mode;
  291. {
  292.     PSLATEX_justify = mode;
  293.     return TRUE;
  294. }
  295.  
  296. TERM_PUBLIC int PSLATEX_text_angle(angle)
  297. int angle;
  298. {
  299.     /* rotated text is put in a short stack, and optionally uses 
  300.      * postscript specials depending on PSLATEX_rotate */
  301.     PSLATEX_angle = angle;
  302.     return TRUE;
  303. }
  304.  
  305.  
  306. TERM_PUBLIC void PSLATEX_reset()
  307. {
  308.     if (PSLATEX_useAuxFile && PSLATEX_auxFile) {
  309.     fclose(PSLATEX_auxFile);
  310.     PSLATEX_auxFile=NULL;
  311.     }
  312. }
  313.  
  314. TERM_PUBLIC void PSLATEX_text()
  315. {
  316.     struct text_command* tc;
  317.  
  318.     if (PSLATEX_useAuxFile) {
  319.     FILE *tmp = outfile;
  320.     outfile = PSLATEX_auxFile;
  321.     PS_text();
  322.     outfile = tmp;
  323.     } else {
  324.     PS_text();
  325.     fprintf(outfile, "}\n");
  326.     }
  327.  
  328.     for (tc = PSLATEX_labels; tc != (struct text_command*)NULL; tc = tc->next) {
  329.     fprintf(outfile, "\\put(%d,%d){", tc->x, tc->y);
  330.     switch (tc->angle) {
  331.     case 0:
  332.         switch (tc->justify) {
  333.         case LEFT:
  334.         fprintf(outfile, (PSLATEX_output
  335.                   ? "\\makebox(0,0)[l]{%s}"
  336.                   : "\\ljust{%s}"), tc->label);
  337.         break;
  338.         case CENTRE:
  339.         fprintf(outfile, (PSLATEX_output
  340.                   ? "\\makebox(0,0){%s}"
  341.                   : "\\cjust{%s}"), tc->label);
  342.         break;
  343.         case RIGHT:
  344.         fprintf(outfile, (PSLATEX_output
  345.                   ? "\\makebox(0,0)[r]{%s}"
  346.                   : "\\rjust{%s}"), tc->label);
  347.         break;
  348.         }
  349.         break;
  350.     case 1: /* put text in a short stack */
  351.         if (PSLATEX_rotate) {
  352.             fprintf(outfile, "%%\n\\special{ps: gsave currentpoint currentpoint translate\n");
  353.             fprintf(outfile, "270 rotate neg exch neg exch translate}%%\n");
  354.         }
  355.         switch (tc->justify) {
  356.         case LEFT:
  357.         fprintf(outfile, (PSLATEX_output
  358.                   ? "\\makebox(0,0)[lb]{\\shortstack{%s}}"
  359.                   : "\\lstack{%s}"),
  360.             tc->label);
  361.         break;
  362.         case CENTRE:
  363.         fprintf(outfile, (PSLATEX_output
  364.                   ? "\\makebox(0,0)[b]{\\shortstack{%s}}"
  365.                   : "\\cstack{%s}"),
  366.             tc->label);
  367.         break;
  368.         case RIGHT:
  369.         fprintf(outfile, (PSLATEX_output
  370.                   ? "\\makebox(0,0)[lt]{\\shortstack{%s}}"
  371.                   : "\\rstack{%s}"),
  372.             tc->label);
  373.         break;
  374.         }
  375.         if (PSLATEX_rotate) {
  376.             fprintf(outfile, "%%\n\\special{ps: currentpoint grestore moveto}%%\n");
  377.         }
  378.     }
  379.     fprintf(outfile, "}\n");
  380.     }
  381.  
  382.     while (PSLATEX_labels) {
  383.     tc = PSLATEX_labels->next;
  384.     free(PSLATEX_labels->label);
  385.     free(PSLATEX_labels);
  386.     PSLATEX_labels = tc;
  387.     }
  388.  
  389.     if (PSLATEX_output)
  390.         fprintf(outfile, "\\end{picture}\n");
  391.     else
  392.     fprintf(outfile, "\\endGNUPLOTpicture\n");
  393. }
  394.  
  395. TERM_PUBLIC void PSLATEX_move(x,y)
  396. unsigned int x,y;
  397. {
  398.     if (PSLATEX_useAuxFile) {
  399.     FILE *tmp = outfile;
  400.     outfile = PSLATEX_auxFile;
  401.     PS_move(x,y);
  402.     outfile=tmp;
  403.     } else {
  404.     PS_move(x,y);
  405.     }
  406. }
  407.  
  408.  
  409. TERM_PUBLIC void PSLATEX_vector(x,y)
  410. unsigned int x,y;
  411. {
  412.  
  413.     if (PSLATEX_useAuxFile) {
  414.     FILE *tmp = outfile;
  415.     outfile = PSLATEX_auxFile;
  416.     PS_vector(x,y);
  417.     outfile = tmp;
  418.     } else {
  419.     PS_vector(x,y);
  420.     }
  421. }
  422.  
  423.  
  424. TERM_PUBLIC void PSLATEX_linetype(lt)
  425. int lt;
  426. {
  427.     if (PSLATEX_useAuxFile) {
  428.     FILE *tmp = outfile;
  429.     outfile = PSLATEX_auxFile;
  430.     PS_linetype(lt);
  431.     outfile = tmp;
  432.     } else {
  433.     PS_linetype(lt);
  434.     }
  435. }
  436.  
  437. TERM_PUBLIC void PSLATEX_point(x,y,number)
  438. unsigned int x,y;
  439. int number;
  440. {
  441.     if (PSLATEX_useAuxFile) {
  442.     FILE *tmp = outfile;
  443.     outfile = PSLATEX_auxFile;
  444.     PS_point(x,y,number);
  445.     outfile = tmp;
  446.     } else
  447.     PS_point(x,y,number);
  448. }
  449. #endif /* TERM_BODY */
  450.  
  451. #ifdef TERM_TABLE
  452.  
  453. #ifndef GOT_POST_PROTO
  454. #define TERM_PROTO_ONLY
  455. #include "post.trm"
  456. #undef TERM_PROTO_ONLY
  457. #endif
  458.  
  459. TERM_TABLE_START(pslatex_driver)
  460.     "pslatex", "LaTeX picture environment with PostScript \\specials",
  461.     PSLATEX_XMAX, PSLATEX_YMAX, PSLATEX_VCHAR, PSLATEX_HCHAR,
  462.     PS_VTIC, PS_HTIC, PSLATEX_options, PSLATEX_init, PSLATEX_reset,
  463.     PSLATEX_text, null_scale, PSLATEX_graphics, PSLATEX_move,
  464.     PSLATEX_vector,    PSLATEX_linetype, PSLATEX_put_text, PSLATEX_text_angle,
  465.     PSLATEX_justify_text, PSLATEX_point, do_arrow, PS_set_font
  466. TERM_TABLE_END(pslatex_driver)
  467.  
  468. #undef LAST_TERM
  469. #define LAST_TERM pslatex_driver
  470.  
  471. TERM_TABLE_START(pstex_driver)
  472.     "pstex", "plain TeX with PostScript \\specials",
  473.     PSLATEX_XMAX, PSLATEX_YMAX, PSLATEX_VCHAR, PSLATEX_HCHAR,
  474.     PS_VTIC, PS_HTIC, PSLATEX_options, PSLATEX_init, PSLATEX_reset,
  475.     PSLATEX_text, null_scale, PSLATEX_graphics, PSLATEX_move,
  476.     PSLATEX_vector,    PSLATEX_linetype, PSLATEX_put_text, PSLATEX_text_angle,
  477.     PSLATEX_justify_text, PSLATEX_point, do_arrow, PS_set_font
  478. TERM_TABLE_END(pstex_driver)
  479.  
  480. #undef LAST_TERM
  481. #define LAST_TERM pstex_driver
  482.  
  483. #endif /* TERM_TABLE */
  484. #endif /* TERM_PROTO_ONLY */
  485.  
  486.  
  487. #ifdef TERM_HELP
  488. START_HELP(pslatex)
  489. "1 pslatex",
  490. "?set terminal pslatex",
  491. "?pslatex",
  492. " There are a few options for the pslatex driver.",
  493. "",
  494. " Syntax:",
  495. "         set terminal pslatex {<color>} {<rotate>} {auxfile}",
  496. "",
  497. " <color> is either `color` or `monochrome`.  If `default` is specified, the",
  498. " plot will have rotated text and be in monochrome, all in one file.  <rotate>",
  499. " is either `rotate` or `norotate` and determines if the vertical axis label",
  500. " is rotated.",
  501. " If `auxfile` is specified, it directs the driver to put the PostScript",
  502. " commands into an auxiliary file instead of directly into the LaTeX file.",
  503. " This is useful if your plots are large, and dvips cannot handle the picture.",
  504. " The PostScript file name for this option is determined by replacing the",
  505. " trailing `.tex` with `.ps` in the output file name.",
  506. "",
  507. " Example:",
  508. "         set term pslatex auxfile    # put PostScript parts in file foo.ps",
  509. "         set output \"foo.tex\""
  510. END_HELP(pslatex)
  511. #endif
  512.  
  513.